package com.company.cloud.user.modules.mgr.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.auth.bean.WebRequestUrlModel;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.constant.BaseConstant;
import com.company.cloud.common.constant.BaseReturnEnum;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.user.modules.api.request.AuthUrlConfigAddRequest;
import com.company.cloud.user.modules.api.request.AuthUrlConfigQueryRequest;
import com.company.cloud.user.modules.api.request.AuthUrlConfigUpdateRequest;
import com.company.cloud.user.modules.api.request.ServiceUrlConfigAddRequest;
import com.company.cloud.user.modules.api.response.AuthUrlConfigResp;
import com.company.cloud.user.modules.base.entity.UrlAuthConfig;
import com.company.cloud.user.modules.base.service.UrlAuthConfigService;
import com.company.cloud.user.modules.cache.utils.UserConvertUtils;
import com.company.cloud.user.modules.mgr.service.UrlAuthConfigMgrService;
import com.company.common.auth.service.SecurityUrlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;

@Service
public class UrlAuthConfigMgrServiceImpl implements UrlAuthConfigMgrService {

    @Autowired
    private UrlAuthConfigService urlAuthConfigService;
    @Autowired
    private SecurityUrlService securityUrlService;

    @Override
    public void addBatch(ServiceUrlConfigAddRequest params) {
        List<UrlAuthConfig> entitys=new ArrayList<UrlAuthConfig>();
        for(WebRequestUrlModel item:params.getServiceUrls()) {
            UrlAuthConfig entity=new UrlAuthConfig();
            entity.setServiceName(params.getServiceName());
            entity.setServicePath(params.getServicePrefix());
            entity.setAuthType(item.getAuthType());
            entity.setMethodUrl(item.getMethodUrl());
            entity.setIsAuto(BaseConstant.YNEnum.YES.getCode());
            entity.setCman(-1);
            entity.setCdt(LocalDateTime.now());
            entity.setCip("127.0.0.1");
            entity.setEman(-1);
            entity.setEdt(LocalDateTime.now());
            entity.setEip("127.0.0.1");
            entitys.add(entity);
        }
        if(entitys.size()>0) {
            urlAuthConfigService.remove(new QueryWrapper<UrlAuthConfig>()
                    .eq("service_name", params.getServiceName())
                    .eq("is_auto", BaseConstant.YNEnum.YES.getCode())
            );
            urlAuthConfigService.saveBatch(entitys);
        }
    }

    @Override
    public void addUrl2Cache() {
        List<UrlAuthConfig> entitys=urlAuthConfigService.list();
        if(!CollectionUtils.isEmpty(entitys)) {
            Map<String, Set<String>> urls=new HashMap<String, Set<String>>();
            entitys.forEach(entity->{
                String url=this.getUrl(entity.getServicePath(), entity.getMethodUrl());
                Set<String> items= urls.get(url);
                if(items==null) {
                    items=new HashSet<String>();
                    urls.put(url, items);
                }
                items.add(entity.getAuthType());
            });
            securityUrlService.initCache(urls);
        }
    }

    @Override
    public IPage<AuthUrlConfigResp> query(AuthUrlConfigQueryRequest request) {
        IPage<UrlAuthConfig> page =  urlAuthConfigService.page(
                new Page<UrlAuthConfig>(request.getPage(), request.getRows()),
                new QueryWrapper<UrlAuthConfig>()
                .eq(StringUtils.hasText(request.getServiceName()),"service_name",request.getServiceName())
                .eq(StringUtils.hasText(request.getServicePath()),"service_path",request.getServicePath())
                .eq(StringUtils.hasText(request.getMethodUrl()),"method_url",request.getMethodUrl())
                .eq(StringUtils.hasText(request.getAuthType()),"auth_type",request.getAuthType())
                .eq(StringUtils.hasText(request.getIsAuto()),"is_auto",request.getIsAuto())
        );
        IPage<AuthUrlConfigResp> data=page.convert(new Function<UrlAuthConfig, AuthUrlConfigResp>() {
            @Override
            public AuthUrlConfigResp apply(UrlAuthConfig entity) {
              return  UserConvertUtils.getAuthUrlConfigResp(entity);
            }
        });
        return data;
    }

    @Override
    public AuthUrlConfigResp add(AuthUrlConfigAddRequest request, LoginSimpleUserInfo userInfo) {
        UrlAuthConfig entity=new UrlAuthConfig();
        entity.setServiceName(request.getServiceName());
        entity.setServicePath(request.getServicePath());
        entity.setMethodUrl(request.getMethodUrl());
        entity.setAuthType(request.getAuthType());
        entity.setIsAuto(BaseConstant.YNEnum.NO.getCode());
        entity.addCreateParam(userInfo);
        entity.addEditParam(userInfo);
        urlAuthConfigService.save(entity);
        return UserConvertUtils.getAuthUrlConfigResp(entity);
    }

    @Override
    public AuthUrlConfigResp update(AuthUrlConfigUpdateRequest request, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(request);
        UrlAuthConfig entity= urlAuthConfigService.getById(request.getId());
        if(entity==null){
            throw  new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        entity.setServiceName(request.getServiceName());
        entity.setServicePath(request.getServicePath());
        entity.setMethodUrl(request.getMethodUrl());
        entity.setAuthType(request.getAuthType());
        entity.setIsAuto(BaseConstant.YNEnum.NO.getCode());
        entity.addEditParam(userInfo);
        urlAuthConfigService.updateById(entity);
        return UserConvertUtils.getAuthUrlConfigResp(entity);
    }

    @Override
    public AuthUrlConfigResp get(Integer id) {
        UrlAuthConfig entity= urlAuthConfigService.getById(id);
        if(entity==null){
            throw  new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        return UserConvertUtils.getAuthUrlConfigResp(entity);
    }

    @Override
    public void del(Integer id, LoginSimpleUserInfo userInfo) {
        urlAuthConfigService.removeById(id);
    }

    private String getUrl(String prefix ,String url) {
        if(StringUtils.isEmpty(prefix) || "/".equals(prefix)) {
            return url;
        }
        return prefix+url;
    }

}
